package com.ai.ubssapp.service;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.ai.ubssapp.bean.RespInfo;
import com.ai.ubssapp.constant.Configs;
import com.ai.ubssapp.constant.Constants;
import com.ai.ubssapp.dao.UserDao;
import com.ai.ubssapp.util.BizHttpClientHelper;
import com.ai.ubssapp.util.BssIntfUtil;
import com.ai.ubssapp.util.DateUtils;
import com.ai.ubssapp.util.EncryptUtil;



@Component("casIntf")
public class CasIntf /*extends AppIntf*/ {
	
	protected Logger log = LoggerFactory.getLogger(CasIntf.class);

//	@Resource(name = "sqlSessionDao")
//	private BaseSqlSessionDao dao;
//
//	@Resource(name = "smsService")
//	private SmsService smsService;
//	
//	protected Common common = SingletonFactory.getInstance(Common.class);
	
	@Resource(name = "userDao")
	private UserDao userDao;
	
	@Resource(name = "configs")
	private Configs configs;
	
	@Resource(name = "bizHttpClientHelper")
	private BizHttpClientHelper bizHttpClientHelper;
	
	/**
	 * cBSS接口地址
	 */
	@Value("${intf.cbss}")
	private String serviceHost;
	
	/**
	 * cBSS 登录接口url
	 */
	@Value("${service.cas.login.addr}")
	private String serviceAddr;
	
	/**
	 * cBSS 登录接口短信验证码是否需要校验
	 */
	@Value("${casIntf.verifyCode.check}")
	private String checkFlag;
	
	
	/**
	 * 登录cas并获取登录参数接口
	 * 
	 * @param param
	 * @return
	 * @throws IOException 
	 * @throws Exception
	 */
	@SuppressWarnings( { "unchecked", "deprecation" })
	public RespInfo login(String staffId, String password,String randomNum) throws Exception {
		String errorMsg = "登录cas并获取登录参数失败";

		RespInfo respInfo = new RespInfo();
		if (StringUtils.isEmpty(staffId)) {
			respInfo.setRespCode(Constants.RESP_CODE_FAILURE);
			respInfo.setRespDesc(errorMsg + "：员工工号为空！");
			return respInfo;
		}

//		// 1、服务地址
//		String serviceHost = HttpRequstUtil.getCbssIntfHost();
//
//		// 2、接口地址
//		String serviceAddr = common.getProperty("service/cas/login/addr");

		// 3、组装url
		String url = serviceHost + serviceAddr;

		// 江苏没redis缓存，省去这一步
//		// 从缓存中取
//		String cacheTime = common.getProperty("service/cas/login/cacheTime", "300");
//		String cacheKey = url + staffId;
//		RespInfo<IData<String, String>> respInfoCache = getRespInfoCache(cacheKey);
//		if (checkRespInfo(respInfoCache)) {
//			respInfoCache.setRespDesc("注意：同一工号" + (Integer.parseInt(cacheTime) / 60) + "分钟之内获取的loginParam是同一个，本次获取时间：" + common.getSysTime() + "，loginParam生成时间：" + respInfoCache.getTime());
//			return respInfoCache;
//		}

		// 江苏没有从bss同步staff表，depart表，area表，省去这步校验
		// 4、查询员工信息 
		final Map<String, Object> staff = userDao.queryUser(staffId);
		if (staff == null) {
			respInfo.setRespCode(Constants.RESP_CODE_FAILURE);
			respInfo.setRespDesc(errorMsg + "：员工工号" + staffId + "不存在！");
			return respInfo;
		}
		staff.put("PASSWORD", password);

		// 江苏没有发送验证码，数据库里也没有验证码的表，省去这一步校验
		//String checkFlag = SpringPropertyHolder.getContextProperty("casIntf.verifyCode.check");
//		if(Constants.CAS_INTF_VERIFYCODE_CHECK_YES.equals(checkFlag)){
//			Map<String, Object> param = new HashMap<String, Object>();
//			param.put("staffId",staffId);
//			param.put("randomNum",randomNum);
//			RespInfo smsRespInfo =  smsService.verifySmsRandomNum(param);
//			if(IntfConstants.RESP_CODE_FAILURE.equals(smsRespInfo.getRespCode())){
//				respInfo.setRespCode(IntfConstants.RESP_CODE_FAILURE);
//				respInfo.setRespDesc(smsRespInfo.getRespDesc());
//				return respInfo;
//			}
//		}
		// 5、请求参数
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("username", staffId);
		params.put("password", password);

		// 6、获取数据
		String responseBody = "";
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			HttpPost httppost = new HttpPost(url);
			httppost.setEntity(new UrlEncodedFormEntity(bizHttpClientHelper.getPostParam(params), "UTF-8"));
			responseBody = httpclient.execute(httppost, new ResponseHandler<String>() {
				public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
					HttpEntity entity = response.getEntity();
					return entity != null ? EntityUtils.toString(entity, "GBK") : null;
				}
			});
			if(log.isDebugEnabled()){
				log.debug(responseBody);
			}
		} catch (Exception e) {
			httpclient.close();
			log.error(errorMsg, e);
			respInfo.setRespCode(Constants.RESP_CODE_FAILURE);// 返回失败代码
			respInfo.setRespDesc(errorMsg + "：" + e.getMessage());// 返回失败信息
			return respInfo;
		}
		
		// 6、组装数据
		Document doc = Jsoup.parse(responseBody);
		Elements eles = doc.select("form");
		if (eles.size() > 0) {
			String action = eles.get(0).attr("action");
			String castgc = action.substring(action.lastIndexOf("/") + 1, action.length());
			String checkCode = doc.select("#checkCode").val();

			Map<String, Object> data = new HashMap<String, Object>();
			data.put("STAFF_ID", staff.get("STAFF_ID"));// 员工工号
			data.put("STAFF_NAME", staff.get("STAFF_NAME"));// 员工名称
			data.put("DEPART_ID", staff.get("DEPART_ID"));// 部门编码
			data.put("DEPART_NAME", staff.get("DEPART_NAME"));// 部门名称
			data.put("CITY_CODE", staff.get("CITY_CODE"));// 区县编码
			data.put("EPARCHY_CODE", staff.get("EPARCHY_CODE"));// 地州编码
			data.put("SERIAL_NUMBER", staff.get("SERIAL_NUMBER"));// 员工手机号
			data.put("CUC_EPARCHY_CODE", staff.get("CUC_EPARCHY_CODE"));// 总部区域编码
			data.put("CUC_DEPART_CODE", staff.get("CUC_DEPART_CODE"));// 总部部门编码
			try {
				String loginParam = constructLoginParam(staff, castgc, checkCode);
				data.put("_LOGIN_PARAM", EncryptUtil.encryptByDES(URLEncoder.encode(loginParam.toString(), Constants.CHARSET_UTF8), configs.securityKey));// 登录参数
			} catch (Exception e) {
			}
			respInfo.setRespCode(Constants.RESP_CODE_SUCCESS);
			respInfo.setData(data);
			respInfo.setTime(DateUtils.toDateTimeStr());// 记录本次生成loginParam时间

			// 放入缓存
			//this.setRespInfoCache(cacheKey, respInfo, cacheTime);
		} else {
			log.error(errorMsg, responseBody);
			respInfo.setRespCode(Constants.RESP_CODE_FAILURE);// 返回失败代码
			respInfo.setRespDesc(errorMsg);// 返回失败信息
			return respInfo;
		}
		return respInfo;
	}

	/**
	 * 构建loginParam
	 * 
	 * @param response
	 * @param staff
	 * @param loginParam
	 * @throws ParseException
	 * @throws IOException
	 */
	private String constructLoginParam(Map<String, Object> staff, String castgc, String checkCode) throws ParseException, IOException {
		StringBuffer loginParam = new StringBuffer();
		loginParam.append("&staffId=" + staff.get("STAFF_ID"));
		loginParam.append("&staffName=" + staff.get("STAFF_NAME"));
		loginParam.append("&departId=" + staff.get("DEPART_ID"));
		loginParam.append("&departName=" + staff.get("DEPART_NAME"));
		loginParam.append("&cityCode=" + staff.get("CITY_CODE"));
		loginParam.append("&eparchyCode=" + staff.get("EPARCHY_CODE"));
		loginParam.append("&cucDepartId=" + staff.get("CUC_DEPART_CODE"));
		loginParam.append("&cucEparchyCode=" + staff.get("CUC_EPARCHY_CODE"));
		loginParam.append("&uniEparchyCode=" + staff.get("UNI_EPARCHY_CODE"));
		loginParam.append("&cucCityCode=" + staff.get("CUC_CITY_CODE"));
		loginParam.append("&uniCityCode=" + staff.get("UNI_CITY_CODE"));
		loginParam.append("&provinceId=" + staff.get("PROVINCE_ID"));
		loginParam.append("&serialNumber=" + staff.get("SERIAL_NUMBER"));
		loginParam.append("&_password=" + staff.get("PASSWORD"));
		loginParam.append("&subSysCode=BSS");
		loginParam.append("&_specCasServer=" + staff.get("PROVINCE_CODE"));
		loginParam.append("&_fromSys=UNP");
		loginParam.append("&_castgc=" + castgc);
		loginParam.append("&_cbssCheckCode=" + checkCode);
		return loginParam.toString();
	}

	/**
	 * 退出cas
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public RespInfo logout(String loginParam) {
		RespInfo respInfo = new RespInfo();
		String msg = "退出cas";
		try {
			boolean flag = bizHttpClientHelper.logoutAll(loginParam);
			if (flag) {
				respInfo.setRespCode(Constants.RESP_CODE_SUCCESS);
				respInfo.setRespDesc(msg + "成功");
			} else {
				respInfo.setRespCode(Constants.RESP_CODE_FAILURE);
				respInfo.setRespDesc(msg + "失败");
			}
		} catch (Exception e) {
			log.error(msg + "失败", e);
			respInfo.setRespCode(Constants.RESP_CODE_FAILURE);
			respInfo.setRespDesc(msg + "失败" + "：" + e.getMessage());
		}
		return respInfo;
	}
}
